package cn.wjzhang.middle.modules.global.service;

import cn.hutool.core.date.DateUtil;
import cn.wjzhang.core.beans.vo.Result;
import cn.wjzhang.core.exception.BootException;
import cn.wjzhang.core.utils.IPUtils;
import cn.wjzhang.middle.modules.global.beans.request.BaseRequest;
import cn.wjzhang.middle.modules.global.beans.response.ValidateResult;
import cn.wjzhang.middle.utils.ValidatorUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.WebConnection;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Objects;

/**
 * 通用service
 * @author wjzhang
 * @date 2021/10/27 10:41
 */
@Slf4j
public abstract class GlobalService<T extends BaseRequest> implements WjBaseService {
    private Class<T> reqClazz;

    @SuppressWarnings("unchecked")
    public GlobalService() {
        Type genericSuperclass = (ParameterizedType)this.getClass().getGenericSuperclass();
        if(genericSuperclass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
            Type[] actualTypeArauments = parameterizedType.getActualTypeArguments();
            this.reqClazz = (Class<T>)actualTypeArauments[0];
        } else {
            this.reqClazz = (Class<T>)genericSuperclass;
        }
    }

    @Override
    public void validate(JSONObject requestJson) {
        T busReqObj = JSON.toJavaObject(requestJson, reqClazz);
        ValidateResult result = ValidatorUtil.validator(busReqObj);
        if(!result.isSuccess()){
            throw new IllegalArgumentException(result.getErrMsg()[0]);
        }
        this.serviceValidate(requestJson);
    }

    /**
     * 服务定制校验<br>
     * 校验不通过，抛出异常
     * @param requestJson
     * @throws IllegalArgumentException
     */
    protected abstract void serviceValidate(JSONObject requestJson) throws IllegalArgumentException;

    @Override
    public Result<?> execute(JSONObject requestJson) {
        // 参数校验
        validate(requestJson);
        // 保存日志
        saveTheCallLog(requestJson);
        try {
            //数据处理
//			log.info("[{}]res[{}]",requestJson.getString("serviceid"), requestJson);
            Result<?> result = dataProcess(requestJson);
            if (result.isSuccess()) {
                log.info("数据响应成功:{}", JSON.toJSONString(result.getResult()));
            }else {
                log.error("数据响应失败信息: {}", result.getMessage());
            }
            return result;
        } catch (BootException e) {
            log.error("数据处理异常," + ",错误信息:" + e.getMessage());
            return Result.error(e.getMessage());
        }
    }

    /**
     * 保存日志
     * @param requestJson 请求参数
     */
    public void saveTheCallLog(JSONObject requestJson) {
        //获取request
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String ipAddr = IPUtils.getClientIp(request);
        requestJson.put("reqTime", DateUtil.now());
        log.info("IP>>>>" +ipAddr + ";请求参数为:"+ JSON.toJSONString(requestJson));
    }
}